#pragma once
#include <cstring>
#include <iostream>
#include <semaphore.h>

class Sem {
public:
  Sem(int n) {
    int r = sem_init(&_sem, 0, n);
    if (r != 0) {
      std::cerr << "Failed to initial semaphore:" << std::strerror(errno)
                << std::endl;
    }
  };

  ~Sem() {
    int r = sem_destroy(&_sem);
    if (r != 0) {
      std::cerr << "Failed to destroy semaphore:" << std::strerror(errno)
                << std::endl;
    }
  };

  void P() {
    int r = sem_wait(&_sem);
    if (r != 0) {
      std::cerr << "Failed to wait semaphore:" << std::strerror(errno)
                << std::endl;
    }
  }

  void V() {
    int r = sem_post(&_sem);
    if (r != 0) {
      std::cerr << "Failed to post semaphore:" << std::strerror(errno)
                << std::endl;
    }
  }

private:
  sem_t _sem;
};
